﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace bin2ota
{
    internal class Program
    {
        // CRC16 Modbus计算函数
        public static ushort CalculateCrc16(byte[] data)
        {
            ushort crc = 0xFFFF;
            foreach (byte datum in data)
            {
                crc ^= datum;
                for (int i = 0; i < 8; i++)
                {
                    if ((crc & 0x0001) != 0)
                    {
                        crc = (ushort)((crc >> 1) ^ 0xA001);
                    }
                    else
                    {
                        crc >>= 1;
                    }
                }
            }
            return crc;
        }

        public static void CreateUpgradeFirmware(string inputFilePath, string outputFilePath)
        {
            try
            {
                // 读取原始固件文件
                byte[] firmwareData = File.ReadAllBytes(inputFilePath);
                // 计算CRC
                ushort crc = CalculateCrc16(firmwareData);
                // 计算需要多少个1024字节的数据包来分包
                int totalPackets = (int)Math.Ceiling((double)firmwareData.Length / 1024);

                // 控制台输出日志
                Console.WriteLine($"原始文件路径: {inputFilePath}");
                Console.WriteLine($"新生成的文件路径: {outputFilePath}");
                Console.WriteLine($"当前文件长度: {firmwareData.Length} 字节");
                Console.WriteLine($"CRC值 (Hex): {crc:X},(十进制): {crc} ");
                Console.WriteLine($"按1024字节拆分为: {totalPackets} 包");

                // 构建升级固件文件
                using (FileStream fs = new FileStream(outputFilePath, FileMode.Create))
                {
                    BinaryWriter writer = new BinaryWriter(fs);
                    // 写入协议头 (假设针头值为544541578) // 0x20750B8A
                    writer.Write(544541578);
                    // 写入固件长度
                    writer.Write(firmwareData.Length);
                    // 写入CRC16
                    writer.Write(crc);
                    // 写入预留区 (52字节，这里用0填充)
                    writer.Write(new byte[52]);
                    // 写入固件数据
                    writer.Write(firmwareData);
                }
                Console.WriteLine("升级固件文件生成成功！");
            }
            catch (Exception ex)
            {
                Console.WriteLine("生成升级固件文件时发生错误: " + ex.Message);
            }
        }

        static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                Console.WriteLine("请提供输入文件路径和输出文件路径！");
                return;
            }
            CreateUpgradeFirmware(args[0], args[1]);
        }
    }
}
